/*******************************************************************************
 * Copyright (c) 2014 Francesco Gabbrielli
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Francesco Gabbrielli - initial API and implementation
 ******************************************************************************/
package it.francescogabbrielli.android.solidalapp.response;

import java.util.List;

import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;

import it.francescogabbrielli.android.solidalapp.Action;
import it.francescogabbrielli.android.solidalapp.Constants;
import it.francescogabbrielli.android.solidalapp.EndpointsLoader;
import it.francescogabbrielli.android.solidalapp.GCMMessageReceiver;
import it.francescogabbrielli.android.solidalapp.MessageActivity;
import it.francescogabbrielli.android.solidalapp.NetworkUtils;
import it.francescogabbrielli.android.solidalapp.R;
import it.francescogabbrielli.android.solidalapp.SolidalApp;
import it.francescogabbrielli.android.solidalapp.SolidalApp.DataKey;
import it.francescogabbrielli.android.solidalapp.actions.EndpointsInsertResponse;
import it.francescogabbrielli.android.solidalapp.deviceendpoint.model.Device;
import it.francescogabbrielli.android.solidalapp.file.ResponseFileActivity;
import it.francescogabbrielli.android.solidalapp.profile.RequestProfileActivity;
import it.francescogabbrielli.android.solidalapp.profile.ResponseProfileActivity;
import it.francescogabbrielli.android.solidalapp.profileendpoint.model.Profile;
import it.francescogabbrielli.android.solidalapp.requestendpoint.model.Request;
import it.francescogabbrielli.android.solidalapp.responseendpoint.model.Response;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.content.Loader;
import android.util.Log;
import android.widget.Toast;
import android.content.Intent;
import android.content.SharedPreferences;

/**
 * Displays all the requests currently active in the neighbourhood
 * and allow accept management 
 */
public class ResponseActivity extends MessageActivity<Response> 
		implements ResponseFragmentListener {
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.baseactivity_response);
		
//		// Show the Up button in the action bar.
//		ActionBar actionBar = getSupportActionBar();
//		if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
//			actionBar.setDisplayHomeAsUpEnabled(true);
//		}
		
		switch(GCMMessageReceiver.Action.valueOf(getIntent())) {
		case GCM_REQUEST_RECEIVED:
		case GCM_FEEDBACK_RECEIVED:
			forwardNotification();
			break;
		default:
			reload(false);
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getSupportMenuInflater().inflate(R.menu.response, menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.action_simulate:
			SharedPreferences prefs = getSharedPreferences(SolidalApp.class.getName(), MODE_PRIVATE);
			Response res = new Response();
			Device device = (Device) app.getData(DataKey.DEVICE);
			ResponseMapFragment fragment = (ResponseMapFragment) getSupportFragmentManager().findFragmentById(R.id.response_map);
			Location loc = app.getStatus().getLocation();
			res.setLatitude(loc.getLatitude());
			res.setLongitude(loc.getLongitude());
			res.setMessage("Simulation n."+prefs.getInt("simulation", 0));
			res.setDeviceId(device.getId());
			res.setRequestId(fragment.getSimulationRequestId());
			res.setTimestamp(System.currentTimeMillis());
			send(res);
			return true;
		case R.id.action_reload:
			reload(true);
			return true;
		case R.id.action_profile:
			Intent intent = new Intent(this, ResponseProfileActivity.class);
			startActivity(intent);
			return true;
		default:
		return super.onOptionsItemSelected(item);
		}
	}
	
	@Override
	public void showRequest(Request request) {

		Response response = (Response) app.getData(DataKey.RESPONSE);
		
		// If this is the request currently responded go to file activity...
		if (response!=null && request.getAccepted() && request.getId().equals(response.getRequestId())) {
			
			Intent intent = new Intent(this, ResponseFileActivity.class);
			startActivity(intent);
			
		// ...else show the accept dialog
		} else {
			
			new RequestDialogFragment()
				.setRequest(request)
				.show(getSupportFragmentManager(), "accept");
			
		}
		
	}
	
	@Override
	public void showAcceptDialog(Request request) {
		
		// Check if already responded
		if (app.getData(DataKey.RESPONSE)!=null) {
			Toast.makeText(this, R.string.response_check_already_responded, Toast.LENGTH_SHORT).show();
			return;
		}
		
		new AcceptDialogFragment()
			.setRequest(request)
			.show(getSupportFragmentManager(), "accept");
	}
	
	@Override
	public void send(Response response) {
		
		hideKeyboard();
				
		// Check location
		Location location = (Location) app.getData(DataKey.ADDRESS_LOCATION);
		if(location==null) {
			if (!checkLocationServices())
				Toast.makeText(this, R.string.check_location, Toast.LENGTH_SHORT).show();
			return;
		}
		response.setLatitude(location.getLatitude());
		response.setLongitude(location.getLongitude());		
		
		// Check network
		if (app.getStatus().getNetworkStatus()!=NetworkUtils.Status.CONNECTED) {
			Toast.makeText(this, R.string.check_network, Toast.LENGTH_SHORT).show();
			return;
		}
		
		// Check registration
		Device device = (Device) app.getData(DataKey.DEVICE);
		if (device==null || app.getStatus().getGcmId()==null) {
			startActivity(new Intent(this, RequestProfileActivity.class));
			Toast.makeText(this, R.string.check_profile, Toast.LENGTH_SHORT).show();
			return;
		}
		response.setDeviceId(device.getId());
		
		// Check profile
		Profile profile = (Profile) app.getData(DataKey.PROFILE);
		if (profile==null || app.getStatus().getGcmId()==null) {
			startActivity(new Intent(this, ResponseProfileActivity.class));
			Toast.makeText(this, R.string.check_profile, Toast.LENGTH_SHORT).show();
			return;
		}
		
		// Check username & phone
//		String phone = device.getTelephoneNumber();
//		if (phone==null)
//			phone = profile.getDefaultPhone();
		response.setSender(profile.getUsername());
		response.setSenderId(profile.getProfileId());

	    try {
	    	
	    	// clear with a new temp response the last response sent 
	    	Response temp = new Response();
	    	temp.setLatitude(response.getLatitude());
	    	temp.setLongitude(response.getLongitude());
	    	temp.setRequestId(response.getRequestId());
	    	app.setData(DataKey.RESPONSE, temp);
	    	
	    	Action.start(this, EndpointsInsertResponse.class, response);
	    	
	    	forceLoader();
	    	
	    } catch(Exception e) {
	    	
	    	app.setData(DataKey.RESPONSE, null);
	    	Log.e(SolidalApp.TAG, "Error: "+e, e);
		    Toast.makeText(this, "Error: "+e, Toast.LENGTH_SHORT).show();
		    reload(true);
		    
	    }
		
	}
	
	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		
		final Bundle extras = intent.getExtras();
		final ResponseMapFragment map = (ResponseMapFragment) getSupportFragmentManager()
				.findFragmentById(R.id.response_map);
		
		if (Action.check(EndpointsInsertResponse.class, intent))
			forceLoader();
		
		switch (GCMMessageReceiver.Action.valueOf(intent)) {
		
		case GCM_REQUEST_RECEIVED:
			addOnResumeAction(new Runnable() {
				@Override
				public void run() {
					app.alert(getString(R.string.request_incoming, extras.getString("message")));
					map.onNewRequest(extras);
				}
			});
			break;
			
		case GCM_FEEDBACK_RECEIVED:
			final long id = Long.parseLong(intent.getStringExtra("id"));
			Response res = (Response) app.getData(DataKey.RESPONSE);
			// accept feedback if referred to current response (TODO: extend this check to all notifications!)
			if (res!=null && !res.getCompleted() && res.getRequestId()!=null && res.getRequestId() == id)
				addOnResumeAction(new Runnable() {
					@Override
					public void run() {
						app.setData(DataKey.RESPONSE, null);
						app.setData(DataKey.FILE_REQUEST, null);
						app.setData(DataKey.FILE_REQUEST_PROFILE, null);
						if (app.getData(DataKey.CHAT_RESPONSE)!=null)
							((List<?>) app.getData(DataKey.CHAT_RESPONSE)).clear();

						app.alert(getString(
								R.string.feedback_notification_title, extras.getString("message")));
						// forward feedback to map
						map.onFeedback(id);
					}
				});
			else
				app.alert(R.string.warning_old_notification);
			break;

		default:
			break;
		}
	}

	@Override
	protected int getLoaderId() {
		return Constants.LOADER_RESPONSE;
	}

	@Override
	public Loader<Response> onCreateLoader(int id, Bundle data) {
		// Make a new loader for the last response
		return new EndpointsLoader<Response>(this, Response.class)
				.setFilters(data)
				.setMethod("getLast");
	}

	@Override
	public void onLoadFinished(Loader<Response> loader, final Response result) {
		
		// if accepting don't try to load
		Response temp = (Response) app.getData(DataKey.RESPONSE);
		boolean sending = temp!=null && temp.getId()==null;
		if (sending) {
			setLoading(false);
			return;
		}
		
		// make sure it is executed when activity is resumed
		addOnResumeAction(new Runnable() {
			public void run() {
				Log.d(SolidalApp.TAG, "CHIC Last response: "+result);
				if (result!=null && !result.getCompleted()) 
					app.setData(DataKey.RESPONSE, result, true);
				else
					app.setData(DataKey.RESPONSE, null, true);
			}
		});
	}

	@Override
	public void onLoaderReset(Loader<Response> loader) {
		
	}
	
}
